package com.dps.recommend.config;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Role;

import java.util.concurrent.*;

@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
@Slf4j
public class TaskExecutorConfig {

    @Bean(name = "taskDpsExecutor")
    @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    public ExecutorService threadPoolTaskExecutor() {
        int coreSize = Runtime.getRuntime().availableProcessors() * 2;
        BlockingQueue<Runnable> executeQueue = new LinkedBlockingQueue(5000);
        BasicThreadFactory factory = (new BasicThreadFactory.Builder()).namingPattern("ExecutorPool" + " thread-%d").daemon(true).build();
        ExecutorService executor = new ThreadPoolExecutor(coreSize, coreSize, 60L, TimeUnit.SECONDS, executeQueue, factory);
        closeThreadPool(executor);
        return executor;
    }

    private static void closeThreadPool(ExecutorService executorService) {
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            if (!executorService.isTerminated()) {
                log.info("executorService shutting down.");
                executorService.shutdown();
                try {
                    if (!executorService.awaitTermination(3L, TimeUnit.SECONDS)) {
                        log.error("executorService shutdown immediately due to wait timeout.");
                        executorService.shutdownNow();
                    }
                } catch (InterruptedException var2) {
                    log.error("executorService shutdown interrupted.");
                    executorService.shutdownNow();
                }
                log.info("executorService shutdown complete.");
            }
        }));
    }

}